// Decompiled on 周六 2月 22 19:31:49 CST 2025 with Zomboid Decompiler v0.1.3 using Vineflower.
package zombie.characters;

import java.util.ArrayList;
import java.util.HashMap;
import se.krka.kahlua.j2se.KahluaTableImpl;
import se.krka.kahlua.vm.KahluaTable;
import se.krka.kahlua.vm.KahluaTableIterator;
import zombie.Lua.LuaManager;
import zombie.characters.AttachedItems.AttachedWeaponDefinitions;
import zombie.core.Rand;
import zombie.core.skinnedmodel.ModelManager;
import zombie.core.skinnedmodel.population.Outfit;
import zombie.core.skinnedmodel.population.OutfitManager;
import zombie.core.skinnedmodel.population.OutfitRNG;
import zombie.iso.IsoGridSquare;
import zombie.iso.IsoMetaGrid;
import zombie.iso.IsoWorld;
import zombie.network.GameServer;
import zombie.util.StringUtils;
import zombie.util.Type;
import zombie.util.list.PZArrayUtil;

public final class ZombiesZoneDefinition {
    private static final ArrayList<ZombiesZoneDefinition.ZZDZone> s_zoneList = new ArrayList();
    private static final HashMap<String, ZombiesZoneDefinition.ZZDZone> s_zoneMap = new HashMap();
    public static boolean bDirty = true;
    private static final ZombiesZoneDefinition.PickDefinition pickDef = new ZombiesZoneDefinition.PickDefinition();
    private static final HashMap<String, ZombiesZoneDefinition.ZZDOutfit> s_customOutfitMap = new HashMap();

    private static void checkDirty() {
        if (bDirty) {
            bDirty = false;
            init();
        }
    }

    private static void init() {
        s_zoneList.clear();
        s_zoneMap.clear();
        KahluaTableImpl kahluaTableImpl0 = Type.tryCastTo(LuaManager.env.rawget("ZombiesZoneDefinition"), KahluaTableImpl.class);
        if (kahluaTableImpl0 != null) {
            KahluaTableIterator kahluaTableIterator = kahluaTableImpl0.iterator();

            while (kahluaTableIterator.advance()) {
                KahluaTableImpl kahluaTableImpl1 = Type.tryCastTo(kahluaTableIterator.getValue(), KahluaTableImpl.class);
                if (kahluaTableImpl1 != null) {
                    ZombiesZoneDefinition.ZZDZone zZDZone = initZone(kahluaTableIterator.getKey().toString(), kahluaTableImpl1);
                    if (zZDZone != null) {
                        s_zoneList.add(zZDZone);
                        s_zoneMap.put(zZDZone.name, zZDZone);
                    }
                }
            }
        }
    }

    private static ZombiesZoneDefinition.ZZDZone initZone(String string, KahluaTableImpl kahluaTableImpl0) {
        ZombiesZoneDefinition.ZZDZone zZDZone = new ZombiesZoneDefinition.ZZDZone();
        zZDZone.name = string;
        zZDZone.femaleChance = kahluaTableImpl0.rawgetInt("femaleChance");
        zZDZone.maleChance = kahluaTableImpl0.rawgetInt("maleChance");
        zZDZone.chanceToSpawn = kahluaTableImpl0.rawgetInt("chanceToSpawn");
        zZDZone.toSpawn = kahluaTableImpl0.rawgetInt("toSpawn");
        KahluaTableIterator kahluaTableIterator = kahluaTableImpl0.iterator();

        while (kahluaTableIterator.advance()) {
            KahluaTableImpl kahluaTableImpl1 = Type.tryCastTo(kahluaTableIterator.getValue(), KahluaTableImpl.class);
            if (kahluaTableImpl1 != null) {
                ZombiesZoneDefinition.ZZDOutfit zZDOutfit = initOutfit(kahluaTableImpl1);
                if (zZDOutfit != null) {
                    zZDOutfit.customName = "ZZD." + zZDZone.name + "." + zZDOutfit.name;
                    zZDZone.outfits.add(zZDOutfit);
                }
            }
        }

        return zZDZone;
    }

    private static ZombiesZoneDefinition.ZZDOutfit initOutfit(KahluaTableImpl kahluaTableImpl) {
        ZombiesZoneDefinition.ZZDOutfit zZDOutfit = new ZombiesZoneDefinition.ZZDOutfit();
        zZDOutfit.name = kahluaTableImpl.rawgetStr("name");
        zZDOutfit.chance = kahluaTableImpl.rawgetFloat("chance");
        zZDOutfit.gender = kahluaTableImpl.rawgetStr("gender");
        zZDOutfit.toSpawn = kahluaTableImpl.rawgetInt("toSpawn");
        zZDOutfit.mandatory = kahluaTableImpl.rawgetStr("mandatory");
        zZDOutfit.room = kahluaTableImpl.rawgetStr("room");
        zZDOutfit.femaleHairStyles = initStringChance(kahluaTableImpl.rawgetStr("femaleHairStyles"));
        zZDOutfit.maleHairStyles = initStringChance(kahluaTableImpl.rawgetStr("maleHairStyles"));
        zZDOutfit.beardStyles = initStringChance(kahluaTableImpl.rawgetStr("beardStyles"));
        return zZDOutfit;
    }

    private static ArrayList<ZombiesZoneDefinition.StringChance> initStringChance(String string0) {
        if (StringUtils.isNullOrWhitespace(string0)) {
            return null;
        } else {
            ArrayList arrayList = new ArrayList();
            String[] string1 = string0.split(";");

            for (String string2 : string1) {
                String[] string3 = string2.split(":");
                ZombiesZoneDefinition.StringChance stringChance = new ZombiesZoneDefinition.StringChance();
                stringChance.str = string3[0];
                stringChance.chance = Float.parseFloat(string3[1]);
                arrayList.add(stringChance);
            }

            return arrayList;
        }
    }

    public static void dressInRandomOutfit(IsoZombie chr) {
        if (!chr.isSkeleton()) {
            IsoGridSquare isoGridSquare = chr.getCurrentSquare();
            if (isoGridSquare != null) {
                ZombiesZoneDefinition.PickDefinition pickDefinition = pickDefinition(isoGridSquare.x, isoGridSquare.y, isoGridSquare.z, chr.isFemale());
                if (pickDefinition == null) {
                    String string = isoGridSquare.getRoom() == null ? null : isoGridSquare.getRoom().getName();
                    Outfit outfit = getRandomDefaultOutfit(chr.isFemale(), string);
                    chr.dressInPersistentOutfit(outfit.m_Name);
                    UnderwearDefinition.addRandomUnderwear(chr);
                } else {
                    applyDefinition(chr, pickDefinition.zone, pickDefinition.table, pickDefinition.bFemale);
                    UnderwearDefinition.addRandomUnderwear(chr);
                }
            }
        }
    }

    public static IsoMetaGrid.Zone getDefinitionZoneAt(int x, int y, int z) {
        ArrayList arrayList = IsoWorld.instance.MetaGrid.getZonesAt(x, y, z);

        for (int _int = arrayList.size() - 1; _int >= 0; _int--) {
            IsoMetaGrid.Zone zone = (IsoMetaGrid.Zone)arrayList.get(_int);
            if ("ZombiesType".equalsIgnoreCase(zone.type) || s_zoneMap.containsKey(zone.type)) {
                return zone;
            }
        }

        return null;
    }

    public static ZombiesZoneDefinition.PickDefinition pickDefinition(int x, int y, int z, boolean bFemale) {
        IsoGridSquare isoGridSquare = IsoWorld.instance.CurrentCell.getGridSquare(x, y, z);
        if (isoGridSquare == null) {
            return null;
        } else {
            String string0 = isoGridSquare.getRoom() == null ? null : isoGridSquare.getRoom().getName();
            checkDirty();
            IsoMetaGrid.Zone zone = getDefinitionZoneAt(x, y, z);
            if (zone == null) {
                return null;
            } else if (zone.spawnSpecialZombies == Boolean.FALSE) {
                return null;
            } else {
                String string1 = StringUtils.isNullOrEmpty(zone.name) ? zone.type : zone.name;
                ZombiesZoneDefinition.ZZDZone zZDZone = (ZombiesZoneDefinition.ZZDZone)s_zoneMap.get(string1);
                if (zZDZone == null) {
                    return null;
                } else {
                    if (zZDZone.chanceToSpawn != -1) {
                        int int0 = zZDZone.chanceToSpawn;
                        int int1 = zZDZone.toSpawn;
                        ArrayList arrayList0 = (ArrayList)IsoWorld.instance.getSpawnedZombieZone().get(zone.getName());
                        if (arrayList0 == null) {
                            arrayList0 = new ArrayList();
                            IsoWorld.instance.getSpawnedZombieZone().put(zone.getName(), arrayList0);
                        }

                        if (arrayList0.contains(zone.id)) {
                            zone.spawnSpecialZombies = true;
                        }

                        if (int1 == -1 || zone.spawnSpecialZombies == null && arrayList0.size() < int1) {
                            if (Rand.Next(100) < int0) {
                                zone.spawnSpecialZombies = true;
                                arrayList0.add(zone.id);
                            } else {
                                zone.spawnSpecialZombies = false;
                                zone = null;
                            }
                        }
                    }

                    if (zone == null) {
                        return null;
                    } else {
                        ArrayList arrayList1 = new ArrayList();
                        ArrayList arrayList2 = new ArrayList();
                        int int2 = zZDZone.maleChance;
                        int int3 = zZDZone.femaleChance;
                        if (int2 > 0 && Rand.Next(100) < int2) {
                            bFemale = false;
                        }

                        if (int3 > 0 && Rand.Next(100) < int3) {
                            bFemale = true;
                        }

                        for (int int4 = 0; int4 < zZDZone.outfits.size(); int4++) {
                            ZombiesZoneDefinition.ZZDOutfit zZDOutfit0 = (ZombiesZoneDefinition.ZZDOutfit)zZDZone.outfits.get(int4);
                            String string2 = zZDOutfit0.gender;
                            String string3 = zZDOutfit0.room;
                            if ((string3 == null || string0 != null && string3.contains(string0))
                                && (!"male".equalsIgnoreCase(string2) || !bFemale)
                                && (!"female".equalsIgnoreCase(string2) || bFemale)) {
                                String string4 = zZDOutfit0.name;
                                boolean _boolean = Boolean.parseBoolean(zZDOutfit0.mandatory);
                                if (_boolean) {
                                    Integer integer = (Integer)zone.spawnedZombies.get(string4);
                                    if (integer == null) {
                                        integer = 0;
                                    }

                                    if (integer < zZDOutfit0.toSpawn) {
                                        arrayList1.add(zZDOutfit0);
                                    }
                                } else {
                                    arrayList2.add(zZDOutfit0);
                                }
                            }
                        }

                        ZombiesZoneDefinition.ZZDOutfit zZDOutfit1;
                        if (!arrayList1.isEmpty()) {
                            zZDOutfit1 = PZArrayUtil.pickRandom(arrayList1);
                        } else {
                            zZDOutfit1 = getRandomOutfitInSetList(arrayList2, true);
                        }

                        if (zZDOutfit1 == null) {
                            return null;
                        } else {
                            pickDef.table = zZDOutfit1;
                            pickDef.bFemale = bFemale;
                            pickDef.zone = zone;
                            return pickDef;
                        }
                    }
                }
            }
        }
    }

    public static void applyDefinition(IsoZombie isoZombie, IsoMetaGrid.Zone zone, ZombiesZoneDefinition.ZZDOutfit zZDOutfit, boolean _boolean) {
        isoZombie.setFemaleEtc(_boolean);
        Outfit outfit = null;
        if (!_boolean) {
            outfit = OutfitManager.instance.FindMaleOutfit(zZDOutfit.name);
        } else {
            outfit = OutfitManager.instance.FindFemaleOutfit(zZDOutfit.name);
        }

        String string = zZDOutfit.customName;
        if (outfit == null) {
            outfit = OutfitManager.instance.GetRandomOutfit(_boolean);
            string = outfit.m_Name;
        } else if (zone != null) {
            Integer integer = (Integer)zone.spawnedZombies.get(outfit.m_Name);
            if (integer == null) {
                integer = 1;
            }

            zone.spawnedZombies.put(outfit.m_Name, integer + 1);
        }

        if (outfit != null) {
            isoZombie.dressInPersistentOutfit(outfit.m_Name);
        }

        ModelManager.instance.ResetNextFrame(isoZombie);
        isoZombie.advancedAnimator.OnAnimDataChanged(false);
    }

    public static Outfit getRandomDefaultOutfit(boolean bFemale, String roomName) {
        ArrayList arrayList = new ArrayList();
        KahluaTable kahluaTable = (KahluaTable)LuaManager.env.rawget("ZombiesZoneDefinition");
        ZombiesZoneDefinition.ZZDZone zZDZone = (ZombiesZoneDefinition.ZZDZone)s_zoneMap.get("Default");

        for (int _int = 0; _int < zZDZone.outfits.size(); _int++) {
            ZombiesZoneDefinition.ZZDOutfit zZDOutfit0 = (ZombiesZoneDefinition.ZZDOutfit)zZDZone.outfits.get(_int);
            String string0 = zZDOutfit0.gender;
            String string1 = zZDOutfit0.room;
            if ((string1 == null || roomName != null && string1.contains(roomName))
                && (string0 == null || "male".equalsIgnoreCase(string0) && !bFemale || "female".equalsIgnoreCase(string0) && bFemale)) {
                arrayList.add(zZDOutfit0);
            }
        }

        ZombiesZoneDefinition.ZZDOutfit zZDOutfit1 = getRandomOutfitInSetList(arrayList, false);
        Outfit outfit = null;
        if (zZDOutfit1 != null) {
            if (bFemale) {
                outfit = OutfitManager.instance.FindFemaleOutfit(zZDOutfit1.name);
            } else {
                outfit = OutfitManager.instance.FindMaleOutfit(zZDOutfit1.name);
            }
        }

        if (outfit == null) {
            outfit = OutfitManager.instance.GetRandomOutfit(bFemale);
        }

        return outfit;
    }

    public static ZombiesZoneDefinition.ZZDOutfit getRandomOutfitInSetList(ArrayList<ZombiesZoneDefinition.ZZDOutfit> arrayList, boolean _boolean) {
        float float0 = 0.0F;

        for (int int0 = 0; int0 < arrayList.size(); int0++) {
            ZombiesZoneDefinition.ZZDOutfit zZDOutfit0 = (ZombiesZoneDefinition.ZZDOutfit)arrayList.get(int0);
            float0 += zZDOutfit0.chance;
        }

        float float1 = Rand.Next(0.0F, 100.0F);
        if (!_boolean || float0 > 100.0F) {
            float1 = Rand.Next(0.0F, float0);
        }

        float float2 = 0.0F;

        for (int int1 = 0; int1 < arrayList.size(); int1++) {
            ZombiesZoneDefinition.ZZDOutfit zZDOutfit1 = (ZombiesZoneDefinition.ZZDOutfit)arrayList.get(int1);
            float2 += zZDOutfit1.chance;
            if (float1 < float2) {
                return zZDOutfit1;
            }
        }

        return null;
    }

    private static String getRandomHairOrBeard(ArrayList<ZombiesZoneDefinition.StringChance> arrayList) {
        float float0 = OutfitRNG.Next(0.0F, 100.0F);
        float float1 = 0.0F;

        for (int _int = 0; _int < arrayList.size(); _int++) {
            ZombiesZoneDefinition.StringChance stringChance = (ZombiesZoneDefinition.StringChance)arrayList.get(_int);
            float1 += stringChance.chance;
            if (float0 < float1) {
                if ("null".equalsIgnoreCase(stringChance.str)) {
                    return "";
                }

                return stringChance.str;
            }
        }

        return null;
    }

    public static void registerCustomOutfits() {
        checkDirty();
        s_customOutfitMap.clear();

        for (ZombiesZoneDefinition.ZZDZone zZDZone : s_zoneList) {
            for (ZombiesZoneDefinition.ZZDOutfit zZDOutfit : zZDZone.outfits) {
                zombie.PersistentOutfits.instance.registerOutfitter(zZDOutfit.customName, true, ZombiesZoneDefinition::ApplyCustomOutfit);
                s_customOutfitMap.put(zZDOutfit.customName, zZDOutfit);
            }
        }
    }

    private static void ApplyCustomOutfit(int _int, String string, IsoGameCharacter isoGameCharacter) {
        ZombiesZoneDefinition.ZZDOutfit zZDOutfit = (ZombiesZoneDefinition.ZZDOutfit)s_customOutfitMap.get(string);
        boolean boolean0 = (_int & -2147483648) != 0;
        IsoZombie isoZombie = Type.tryCastTo(isoGameCharacter, IsoZombie.class);
        if (isoZombie != null) {
            isoZombie.setFemaleEtc(boolean0);
        }

        isoGameCharacter.dressInNamedOutfit(zZDOutfit.name);
        if (isoZombie == null) {
            zombie.PersistentOutfits.instance.removeFallenHat(_int, isoGameCharacter);
        } else {
            AttachedWeaponDefinitions.instance.addRandomAttachedWeapon(isoZombie);
            isoZombie.addRandomBloodDirtHolesEtc();
            boolean boolean1 = isoGameCharacter.isFemale();
            if (boolean1 && zZDOutfit.femaleHairStyles != null) {
                isoZombie.getHumanVisual().setHairModel(getRandomHairOrBeard(zZDOutfit.femaleHairStyles));
            }

            if (!boolean1 && zZDOutfit.maleHairStyles != null) {
                isoZombie.getHumanVisual().setHairModel(getRandomHairOrBeard(zZDOutfit.maleHairStyles));
            }

            if (!boolean1 && zZDOutfit.beardStyles != null) {
                isoZombie.getHumanVisual().setBeardModel(getRandomHairOrBeard(zZDOutfit.beardStyles));
            }

            zombie.PersistentOutfits.instance.removeFallenHat(_int, isoGameCharacter);
        }
    }

    public static int pickPersistentOutfit(IsoGridSquare square) {
        if (!GameServer.bServer) {
            return 0;
        } else {
            boolean boolean0 = Rand.Next(2) == 0;
            ZombiesZoneDefinition.PickDefinition pickDefinition = pickDefinition(square.x, square.y, square.z, boolean0);
            Outfit outfit;
            if (pickDefinition == null) {
                String string0 = square.getRoom() == null ? null : square.getRoom().getName();
                outfit = getRandomDefaultOutfit(boolean0, string0);
            } else {
                boolean0 = pickDefinition.bFemale;
                String string1 = pickDefinition.table.name;
                if (boolean0) {
                    outfit = OutfitManager.instance.FindFemaleOutfit(string1);
                } else {
                    outfit = OutfitManager.instance.FindMaleOutfit(string1);
                }
            }

            if (outfit == null) {
                boolean boolean1 = true;
            } else {
                int _int = zombie.PersistentOutfits.instance.pickOutfit(outfit.m_Name, boolean0);
                if (_int != 0) {
                    return _int;
                }

                boolean boolean2 = true;
            }

            return 0;
        }
    }

    public static final class PickDefinition {
        IsoMetaGrid.Zone zone;
        ZombiesZoneDefinition.ZZDOutfit table;
        boolean bFemale;
    }

    private static final class StringChance {
        String str;
        float chance;
    }

    private static final class ZZDOutfit {
        String name;
        String customName;
        float chance;
        int toSpawn;
        String gender;
        String mandatory;
        String room;
        ArrayList<ZombiesZoneDefinition.StringChance> femaleHairStyles;
        ArrayList<ZombiesZoneDefinition.StringChance> maleHairStyles;
        ArrayList<ZombiesZoneDefinition.StringChance> beardStyles;
    }

    private static final class ZZDZone {
        String name;
        int femaleChance;
        int maleChance;
        int chanceToSpawn;
        int toSpawn;
        final ArrayList<ZombiesZoneDefinition.ZZDOutfit> outfits = new ArrayList();
    }
}
